<template>
    <div>

        <div class="controls-box2" style="margin-bottom: 5px;">
            <section>
                <el-row>
                    <el-form label-width="50px" size="mini">
                        <el-form-item :label="item.name" v-for="(item,key) in formData.properties" :key="key">
                            <el-slider v-model="item.value" :min="item.min" :max="item.max" :step="item.step" show-input></el-slider>
                        </el-form-item>
                        <el-form-item label="动画">
                            <el-switch
                                    v-model="animationSwitch"
                                    active-color="#13ce66"
                                    inactive-color="#ff4949">
                            </el-switch>
                        </el-form-item>
                    </el-form>
                </el-row>
                <el-row>
                    <el-button style="margin-top:10px;" type="primary" size="mini" @click="goHome">回到初始位置</el-button>
                </el-row>
            </section>
        </div>
        <div id="container" style="height: 800px;"></div>
    </div>
</template>

<script>
    import * as THREE from 'three'
    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
    import { createMultiMaterialObject } from 'three/examples/jsm/utils/SceneUtils.js'
    export default {
        data() {
            return {
                cubeCacheKey: 'cubeCacheKey1',
                animationSwitch: true,
                formData: {
                    properties: {
                        depth: {
                            name: '长',
                            value: 2,
                            min: 0,
                            max: 100,
                            step: 1
                        },
                        width: {
                            name: '宽',
                            value: 2,
                            min: 0,
                            max: 100,
                            step: 1
                        },
                        height: {
                            name: '高',
                            value: 2,
                            min: 0,
                            max: 100,
                            step: 1
                        },
                        // depthSegments: {
                        //     name: '长间隔',
                        //     value: 4,
                        //     min: 1,
                        //     max: 20,
                        //     step: 1
                        // },
                        // widthSegments: {
                        //     name: '宽间隔',
                        //     value: 4,
                        //     min: 1,
                        //     max: 20,
                        //     step: 1
                        // },
                        // heightSegments: {
                        //     name: '高间隔',
                        //     value: 4,
                        //     min: 1,
                        //     max: 20,
                        //     step: 1
                        // },

                    },
                },
                mesh: null,
                camera: null,
                scene: null,
                renderer: null,
                controls: null
            }
        },
        mounted() {
            let formData = this.$localStorage.get(this.cubeCacheKey)
            if (formData) {
                this.formData = formData
            }
            this.init()
        },
        methods: {
            goHome() {
                this.mesh.rotation.x = 0
                this.mesh.rotation.y = 0
                this.mesh.rotation.z = 0
            },
            formatTooltip(val) {
                return val
            },
            // 初始化
            init() {
                this.createScene() // 创建场景
                this.createMesh() // 创建网格模型
                this.createLight() // 创建光源
                this.createCamera() // 创建相机
                this.createRender() // 创建渲染器
                this.createControls() // 创建控件对象
                this.render() // 渲染
            },
            // 创建场景
            createScene() {
                this.scene = new THREE.Scene()
            },
            // 创建网格模型
            createMesh() {
                //创建立方体
                const geom = new THREE.BoxGeometry(
                    this.formData.properties.width.value,
                    this.formData.properties.height.value,
                    this.formData.properties.depth.value,
                    Math.round(this.formData.properties.width.value),
                    Math.round(this.formData.properties.height.value),
                    Math.round(this.formData.properties.depth.value)
                )
                // 创建材质
                const meshMaterial = new THREE.MeshNormalMaterial({
                    side: THREE.DoubleSide
                })
                const wireFrameMat = new THREE.MeshBasicMaterial({ wireframe: true })

                // 添加组合材质
                this.mesh = createMultiMaterialObject(geom, [
                    meshMaterial,
                    wireFrameMat
                ])

                // 网格对象添加到场景中
                this.scene.add(this.mesh)
            },

            // 创建光源
            createLight() {
                // 环境光
                const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光
                this.scene.add(ambientLight) // 将环境光添加到场景

                const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯
                spotLight.position.set(-40, 60, -10)
                spotLight.castShadow = true
                this.scene.add(spotLight)
            },
            // 创建相机
            createCamera() {
                const element = document.getElementById('container')
                const width = element.clientWidth // 窗口宽度
                const height = element.clientHeight // 窗口高度
                const k = width / height // 窗口宽高比
                // PerspectiveCamera( fov, aspect, near, far )
                this.camera = new THREE.PerspectiveCamera(35, k, 0.1, 1000)
                this.camera.position.set(-80, 60, 40) // 设置相机位置

                this.camera.lookAt(new THREE.Vector3(10, 0, 0)) // 设置相机方向
                this.scene.add(this.camera)
            },
            // 创建渲染器
            createRender() {
                const element = document.getElementById('container')
                this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
                this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
                this.renderer.shadowMap.enabled = true // 显示阴影
                this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
                this.renderer.setClearColor(0x3f3f3f, 1) // 设置背景颜色
                element.appendChild(this.renderer.domElement)
            },

            // 更新属性
            updateFun() {
                const tempRotationY = this.mesh.rotation.x
                this.scene.remove(this.mesh)
                this.createMesh()
                let delta = 0
                if (this.animationSwitch) {
                    delta = 0.01
                }
                this.mesh.rotation.x = tempRotationY + delta
            },
            render() {
                this.updateFun()
                this.renderer.render(this.scene, this.camera)
                requestAnimationFrame(this.render)
            },
            // 创建控件对象
            createControls() {
                this.controls = new OrbitControls(this.camera, this.renderer.domElement)
            }
        },
        watch: {
            formData: {
                deep: true,
                handler() {
                    this.$localStorage.set(this.cubeCacheKey, this.formData, 4 * 60 * 60 * 1000)
                }
            },
        },
    }
</script>
<style>
    #container {
        position: absolute;
        width: 100%;
        height: 100%;
    }
    .controls-box {
        position: fixed;
        right: 5px;
        top: 5px;
        width: 300px;
        padding: 10px;
        background-color: #fff;
        border: 1px solid #c3c3c3;
    }
    .vertice-span {
        line-height: 38px;
        padding: 0 2px 0 10px;
    }
</style>

